package com.ruoyi.web.controller.taskAssess;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ExecUtil;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.SseEmitterUtils;
import com.ruoyi.common.utils.biz.BizModule;
import com.ruoyi.common.utils.biz.CommonUtil;
import com.ruoyi.common.utils.biz.PathUtil;
import com.ruoyi.common.utils.biz.ResultSaveModule;
import com.ruoyi.dj.mapper.TerrMagnetismMapper;
import com.ruoyi.web.server.entity.ParamFileSave;
import com.ruoyi.web.server.service.ParamFileSaveService;
import com.ruoyi.web.vo.SpaceLaunchVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.File;
import java.nio.channels.FileChannel;
import java.nio.file.StandardOpenOption;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 *  航天发射任务大气模型评估
 * </p>
 *
 * @author liuhl
 * @since 2024-06-04
 */
@RestController
@RequestMapping("/spaceLaunch")
@AllArgsConstructor
@Slf4j
@Api(tags = "典型任务评估-航天发射任务大气模型评估")
public class SpaceLaunchController {

    private ParamFileSaveService paramFileSaveService;
    private TerrMagnetismMapper queryMapper;


    @GetMapping("/launchTime")
    @ApiOperation(value = "获取发射时间上界限", notes = "获取发射时间上界限", httpMethod = "GET")
    public AjaxResult getTimeList() {

        //俞娜 6-28 16:05:30
        //"SWDATA_OBS_AP", "SWDATA_OBS_F107"
        //
        //俞娜 6-28 16:05:56
        //根据数据库两张库表最后的时间进行限制
        //假如两者表中时间最大是 2024-6-1，则给前端返回 2024-6-1, 2024-6-2及以后的时间用户不可以选择。
        String tableName1 = "SWDATA_OBS_AP";
        String tableName2 = "SWDATA_OBS_F107";
        String time1 = queryMapper.getPredictTime(tableName1, null).substring(0,10);
        String time2 = queryMapper.getPredictTime(tableName2, null).substring(0,10);
        if (time1.compareTo(time2) >= 0){
            return AjaxResult.success(time2);
        }
        return AjaxResult.success(time1);
    }


    @GetMapping("/time")
    @ApiOperation(value = "获取评估时间列表", notes = "根据【发射时间】获取评估时间列表", httpMethod = "GET")
    @ApiImplicitParam(name ="launchTime",value="发射时间(yyyy-mm-dd)",type = "String",required = true,paramType="query",dataTypeClass = String.class)
    public AjaxResult getTimeList(String launchTime) {
        String codePath = PathUtil.codeModuleDir(BizModule.TASK_ASSESS)  + PathUtil.moduleDirs().getTaskAssess().get("assessTimes");
        String command = "python "+codePath+" "+launchTime;
        String results = ExecUtil.execCmdWithResult(command);
        if (results == null || !results.contains("###")){
            return AjaxResult.error(results);
        }
        String timeListJsonStr = results.split("###")[1];
        //List<String> timeList = JSONUtil.parseArray(timeListJsonStr).toList(String.class);
        return AjaxResult.success(timeListJsonStr);
    }

    @GetMapping("/locations")
    @ApiOperation(value = "获取区域位置列表", notes = "根据【评估时间】获取区域位置列表", httpMethod = "GET")
    @ApiImplicitParam(name ="assessTime",value="发射时间(yyyy-mm-dd)",type = "String",required = true,paramType="query",dataTypeClass = String.class)
    public AjaxResult getLocations(String assessTime) {
        String codePath = PathUtil.codeModuleDir(BizModule.TASK_ASSESS)  + PathUtil.moduleDirs().getTaskAssess().get("locations");
        String originDir = PathUtil.outputDir() +
                PathUtil.moduleDirs().getCollect().get("dir") +
                PathUtil.moduleDirs().getCollect().get("origin");
        String command = "python "+codePath+" "+originDir+" "+assessTime;
        String results = ExecUtil.execCmdWithResult(command);
        if (results == null || !results.contains("###")){
            return AjaxResult.error(results);
        }
        String locationListJsonStr = results.split("###")[1];
        //List<String> locationList = JSONUtil.parseArray(locationListJsonStr).toList(String.class);
        return AjaxResult.success(locationListJsonStr);
    }


    @PostMapping("/save")
    @ApiOperation(value = "结果保存", notes = "保存页面参数和结果文件", httpMethod = "POST")
    public AjaxResult saveResult(@RequestBody SpaceLaunchVo vo) {

        //1.参数整理
        String time = vo.getTime();
        String locations = vo.getLocations();
        String models = vo.getModels();
        String txtPath = vo.getTxtPath();
        if (StrUtil.isBlank(time) || StrUtil.isBlank(locations) || StrUtil.isBlank(models) || StrUtil.isBlank(txtPath)){
            return AjaxResult.error("入参有空值");
        }

        String delimiter = "____"; //4个下划线
        String params = new StringBuilder()
                .append(time).append(delimiter)
                .append(locations).append(delimiter)
                .append(models).toString();

        ParamFileSave dbEntity = paramFileSaveService.getOne(new LambdaQueryWrapper<ParamFileSave>().eq(ParamFileSave::getParams, params));
        if (dbEntity != null){
            return AjaxResult.success();
        }

        //2.临时文件 运输到 永久空间
        File file = new File(txtPath);
        if (!file.exists()){
            return AjaxResult.error("计算结果文件已不存在");
        }
        String outputPath = txtPath.replace(PathUtil.tmpDir(), PathUtil.outputDir());
        try {
            FileChannel from = FileChannel.open(file.toPath(), StandardOpenOption.READ);
            File toFile = new File(outputPath);
            if (toFile.exists()){
                toFile.delete();
            }
            FileChannel to = FileChannel.open(toFile.toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.READ);
            from.transferTo(0, from.size(), to);
            from.close();
            to.close();
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }finally {
            if (file.exists()){
                file.delete();
            }
        }

        //3.保存
        ParamFileSave saveEntity = ParamFileSave.builder()
                .params(params)
                .filePath(outputPath)
                .createTime(new Date())
                .build();
        paramFileSaveService.save(saveEntity);

        return AjaxResult.success();
    }


    @PostMapping("/cal")
    @ApiOperation(value = "计算评估", notes = "根据时间、位置、模型进行计算评估", httpMethod = "POST")
    public AjaxResult calculate(@RequestBody SpaceLaunchVo vo) {

        String codePath = PathUtil.codeModuleDir(BizModule.TASK_ASSESS)  + PathUtil.moduleDirs().getTaskAssess().get("spaceLaunch");
        String originDir = PathUtil.outputDir() +
                PathUtil.moduleDirs().getCollect().get("dir") +
                PathUtil.moduleDirs().getCollect().get("origin");
        String tmpDir = PathUtil.tmpModuleDir(BizModule.TASK_ASSESS);

        String time = vo.getTime();
        String locations = vo.getLocations();
        String models = vo.getModels();

        String delimiter = "____"; //4个下划线
        String params = new StringBuilder()
                .append(time).append(delimiter)
                .append(locations).append(delimiter)
                .append(models).toString();

        ParamFileSave dbEntity = paramFileSaveService.getOne(new LambdaQueryWrapper<ParamFileSave>().eq(ParamFileSave::getParams, params));
        String txtPath;
        if (dbEntity != null){
            txtPath = dbEntity.getFilePath();
        }else {
            //python spach_launch_eval.py /dgdq/output/collect/origin 2014-09-01  27.85:-40.73,39.61:-67.88  COESA62,COESA76 /dgdq/tmp/taskAssess
            String command = "python "+codePath+" "+originDir+" "+time+" "+locations+" "+models+" "+tmpDir;
            String results = ExecUtil.execCmdWithResult(command);
            if (results == null || !results.contains("###")){
                return AjaxResult.error(results);
            }
            txtPath = results.split("###")[1];
        }

        String content = CommonUtil.readStrData(new File(txtPath), null);
        Map<String, JSONObject> contentMap = JSONUtil.toBean(content, Map.class);
        List<String> locationList = vo.getLocationList();

        Map<String,Object> resultMap = new HashMap<>();
        Map<String,Object> locationAndHeightMap = new HashMap<>();

        Map<String,Object> modelDataMap = (Map<String,Object>)contentMap.get("modelData");

        //1.观测值和参评模型模拟值分布结果图
        Map<String,Object> simuMap = new HashMap<>();
        locationList.forEach(location -> {
            Map<String,Object> modelDataAndHeightMap = (Map<String,Object>)modelDataMap.get(location + "_Simu");
            Object densityData = modelDataMap.get(location + "_Density");
            Object heightData = modelDataMap.get(location + "_Height");
            modelDataAndHeightMap.put("Density",densityData);
            modelDataAndHeightMap.put("Height",heightData);

            locationAndHeightMap.put(location, heightData); //顺便记录下高度数组，后面要用
            simuMap.put(location, modelDataAndHeightMap);
        });
        resultMap.put("simu", simuMap);

        Map<String,Object> errorDataMap = (Map<String,Object>) contentMap.get("errorData");

        //2.收集 图2 、图3 所需的数据信息

        Map<String,Map<String,Map<String,Object>>> absoluteRelativeMap = new HashMap<>();
        Map<String,Map<String,Object>> coeeMap = new HashMap<>();

        // 这三个errorType都是 模型、站点、resultType
        Map<String,Map<String,Map<String,Object>>> rootMap = new HashMap<>();
        Map<String,Map<String,Map<String,Object>>> absoluteErrorMap = new HashMap<>();
        Map<String,Map<String,Map<String,Object>>> relativeErrorMap = new HashMap<>();

        errorDataMap.entrySet().forEach(entry -> {
            String key = entry.getKey();
            Object value = entry.getValue();

            //收集图2 所需的数据信息
            if (key.contains("absolute_error#result") || key.contains("relative_error#result")){
                //39.61,-67.88#COESA62#relative_error#result：
                key = key.replace("_error#result", "");
                String[] mapKeyArr = key.split("#");
                String location = mapKeyArr[0];
                String model = mapKeyArr[1];
                String errorType = mapKeyArr[2];

                Map<String, Map<String, Object>> errorAndModelMap = absoluteRelativeMap.get(location);
                if (CollUtil.isEmpty(errorAndModelMap)){
                    errorAndModelMap = new HashMap<>();
                    Map<String, Object> dataMap = new HashMap<>();
                    dataMap.put(model, value);
                    dataMap.put("Height", locationAndHeightMap.get(location));
                    errorAndModelMap.put(errorType, dataMap);
                    absoluteRelativeMap.put(location, errorAndModelMap);
                }else {
                    Map<String, Object> dataMap = errorAndModelMap.get(errorType);
                    if (CollUtil.isEmpty(dataMap)){
                        dataMap = new HashMap<>();
                    }
                    dataMap.put(model, value);
                    dataMap.put("Height", locationAndHeightMap.get(location));
                    errorAndModelMap.put(errorType, dataMap);
                    absoluteRelativeMap.put(location, errorAndModelMap);
                }
                return;
            }

            //收集图3 和 表格 所需的数据信息
            // key = "39.61,-67.88#COESA62#absolute_error#confidenceInterval："
            key = key.replace("：","");
            String[] mapKeyArr = key.split("#");
            String location = mapKeyArr[0];
            String model = mapKeyArr[1];
            String errorType = mapKeyArr[2];

            if ("corrCoee".equalsIgnoreCase(errorType)){ // 39.61,-67.88#COESA62#corrCoee 相关系数是3层，所以就一个简单MAP
                Map<String, Object> locationAndCoee = coeeMap.get(model);
                if (CollUtil.isEmpty(locationAndCoee)){
                    locationAndCoee = new HashMap<>();
                }
                locationAndCoee.put(location, value);
                coeeMap.put(model, locationAndCoee); //前端希望是个数组
                return;
            }

            String resultType = mapKeyArr[3];

            // 这三个errorType都是 模型、站点、resultType
            if ("root_mean_square_error".equalsIgnoreCase(errorType)){
                Map<String, Map<String, Object>> locationAndResultMap = rootMap.get(model);
                if (CollUtil.isEmpty(locationAndResultMap)){
                    locationAndResultMap = new HashMap<>();
                    Map<String, Object> dataMap = new HashMap<>();
                    dataMap.put(resultType, value);
                    locationAndResultMap.put(location, dataMap);
                    rootMap.put(model, locationAndResultMap);
                }else {
                    Map<String, Object> dataMap = locationAndResultMap.get(location);
                    if (CollUtil.isEmpty(dataMap)){
                        dataMap = new HashMap<>();
                    }
                    dataMap.put(resultType, value);
                    locationAndResultMap.put(location, dataMap);
                    rootMap.put(model, locationAndResultMap);
                }
            }

            if ("relative_error".equalsIgnoreCase(errorType)){
                Map<String, Map<String, Object>> locationAndResultMap = relativeErrorMap.get(model);
                if (CollUtil.isEmpty(locationAndResultMap)){
                    locationAndResultMap = new HashMap<>();
                    Map<String, Object> dataMap = new HashMap<>();
                    dataMap.put(resultType, value);
                    locationAndResultMap.put(location, dataMap);
                    relativeErrorMap.put(model, locationAndResultMap);
                }else {
                    Map<String, Object> dataMap = locationAndResultMap.get(location);
                    if (CollUtil.isEmpty(dataMap)){
                        dataMap = new HashMap<>();
                    }
                    dataMap.put(resultType, value);
                    locationAndResultMap.put(location, dataMap);
                    relativeErrorMap.put(model, locationAndResultMap);
                }

            }

            if ("absolute_error".equalsIgnoreCase(errorType)){
                Map<String, Map<String, Object>> locationAndResultMap = absoluteErrorMap.get(model);
                if (CollUtil.isEmpty(locationAndResultMap)){
                    locationAndResultMap = new HashMap<>();
                    Map<String, Object> dataMap = new HashMap<>();
                    dataMap.put(resultType, value);
                    locationAndResultMap.put(location, dataMap);
                    absoluteErrorMap.put(model, locationAndResultMap);
                }else {
                    Map<String, Object> dataMap = locationAndResultMap.get(location);
                    if (CollUtil.isEmpty(dataMap)){
                        dataMap = new HashMap<>();
                    }
                    dataMap.put(resultType, value);
                    locationAndResultMap.put(location, dataMap);
                    absoluteErrorMap.put(model, locationAndResultMap);
                }
            }
        });

        //3.大气模型误差结果统计图
        resultMap.put("absolute_relative",absoluteRelativeMap);
        //4.大气模型误差评估结果统计图
        Map<String, Object> resultErrorMap = new HashMap<>();
        resultErrorMap.put("x", locationList);

        //<model,<location,resultType>>
        Map<String, List<Object>> avg_absolute = absoluteErrorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> {
            return locationList.stream().map(location -> {
                return absoluteErrorMap.get(entry.getKey()).get(location).get("averageResult");
            }).collect(Collectors.toList());
        }));

        Map<String, List<Object>> avg_relative = relativeErrorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> {
            return locationList.stream().map(location -> {
                return relativeErrorMap.get(entry.getKey()).get(location).get("averageResult");
            }).collect(Collectors.toList());
        }));

        Map<String, List<Object>> coee = coeeMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> {
            return locationList.stream().map(location -> {
                return coeeMap.get(entry.getKey()).get(location);
            }).collect(Collectors.toList());
        }));

        Map<String, List<Object>> root = rootMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> {
            return locationList.stream().map(location -> {
                return rootMap.get(entry.getKey()).get(location).get("result");
            }).collect(Collectors.toList());
        }));

        resultErrorMap.put("avg_absolute", avg_absolute);
        resultErrorMap.put("avg_relative", avg_relative);
        resultErrorMap.put("coee", coee);
        resultErrorMap.put("root", root);

        resultMap.put("error_data",resultErrorMap);

        //表格开始
        List<Map<String,Object>> tableData = new ArrayList<>();
        List<String> modelList = rootMap.entrySet().stream().map(Map.Entry::getKey).distinct().collect(Collectors.toList());
        locationList.forEach( location -> {
            modelList.forEach( model -> {
                Map<String, Object> dataMap = MapUtil.builder(new HashMap<String, Object>())
                        .put("location", location)
                        .put("model", model)
                        .put("corrCoee", coeeMap.get(model).get(location))
                        .put("root", rootMap.get(model).get(location).get("confidenceInterval"))
                        .put("avgAbsolute", absoluteErrorMap.get(model).get(location).get("confidenceInterval"))
                        .put("avgRelative", relativeErrorMap.get(model).get(location).get("confidenceInterval"))
                        .build();
                tableData.add(dataMap);
            });
        });
        resultMap.put("table", tableData);

        //3. 最佳策略结果, 例如：【强磁暴期】最优模型为: 【JB2008】
        List<String> bestModelStrategyList = new JSONArray(contentMap.get("bestModelStrategy")).toList(String.class);
        String result = bestModelStrategyList.stream().map(bestModelStrategy -> {
            String[] split = bestModelStrategy.split("#");
            String location = split[1];
            String model = split[3];
            return location + "最优模型为: " + model;
        }).collect(Collectors.joining("；"));
        resultMap.put("result", result);

        //4. txt文件也要加上
        List<String> list = Stream.of(txtPath).collect(Collectors.toList());
        resultMap.put("resultData", JSONUtil.toJsonStr(list));
        resultMap.put("module", ResultSaveModule.TASK_ASSESS);
        resultMap.put("submodule", ResultSaveModule.TASK_ASSESS_LAUNCH);
        return AjaxResult.success(resultMap);
    }


    @ApiOperation(value = "建立连接", notes = "建立连接")
    @GetMapping(path = "subscribe", produces = {MediaType.TEXT_EVENT_STREAM_VALUE})
    public SseEmitter push(String id, String flag) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        return SseEmitterUtils.connect(id+loginUser.getUsername(), flag);
    }


    public static void main(String[] args) {

        String txtPath = "C:\\Users\\HTHT\\Desktop\\fsdownload\\SpaceLaunch.txt.txt";

        String content = CommonUtil.readStrData(new File(txtPath), null);
        Map<String, JSONObject> contentMap = JSONUtil.toBean(content, Map.class);
        List<String> locationList = Stream.of("39.61,-67.88","27.85,-40.73").collect(Collectors.toList());

        Map<String,Object> resultMap = new HashMap<>();
        Map<String,Object> locationAndHeightMap = new HashMap<>();

        Map<String,Object> modelDataMap = (Map<String,Object>)contentMap.get("modelData");

        //1.观测值和参评模型模拟值分布结果图
        Map<String,Object> simuMap = new HashMap<>();
        locationList.forEach(location -> {
            Map<String,Object> modelDataAndHeightMap = (Map<String,Object>)modelDataMap.get(location + "_Simu");
            Object densityData = modelDataMap.get(location + "_Density");
            Object heightData = modelDataMap.get(location + "_Height");
            modelDataAndHeightMap.put("Density",densityData);
            modelDataAndHeightMap.put("Height",heightData);

            locationAndHeightMap.put(location, heightData); //顺便记录下高度数组，后面要用
            simuMap.put(location, modelDataAndHeightMap);
        });
        resultMap.put("simu", simuMap);

        Map<String,Object> errorDataMap = (Map<String,Object>) contentMap.get("errorData");

        //2.收集 图2 、图3 所需的数据信息

        Map<String,Map<String,Map<String,Object>>> absoluteRelativeMap = new HashMap<>();
        Map<String,Map<String,Object>> coeeMap = new HashMap<>();

        // 这三个errorType都是 模型、站点、resultType
        Map<String,Map<String,Map<String,Object>>> rootMap = new HashMap<>();
        Map<String,Map<String,Map<String,Object>>> absoluteErrorMap = new HashMap<>();
        Map<String,Map<String,Map<String,Object>>> relativeErrorMap = new HashMap<>();

        errorDataMap.entrySet().forEach(entry -> {
            String key = entry.getKey();
            Object value = entry.getValue();

            //收集图2 所需的数据信息
            if (key.contains("absolute_error#result") || key.contains("relative_error#result")){
                //39.61,-67.88#COESA62#relative_error#result：
                key = key.replace("_error#result：", "");
                String[] mapKeyArr = key.split("#");
                String location = mapKeyArr[0];
                String model = mapKeyArr[1];
                String errorType = mapKeyArr[2];

                Map<String, Map<String, Object>> errorAndModelMap = absoluteRelativeMap.get(location);
                if (CollUtil.isEmpty(errorAndModelMap)){
                    errorAndModelMap = new HashMap<>();
                    Map<String, Object> dataMap = new HashMap<>();
                    dataMap.put(model, value);
                    errorAndModelMap.put(errorType, dataMap);
                    absoluteRelativeMap.put(location, errorAndModelMap);
                }else {
                    Map<String, Object> dataMap = errorAndModelMap.get(errorType);
                    if (CollUtil.isEmpty(dataMap)){
                        dataMap = new HashMap<>();
                    }
                    dataMap.put(model, value);
                    errorAndModelMap.put(errorType, dataMap);
                    absoluteRelativeMap.put(location, errorAndModelMap);
                }
                return;
            }

            //收集图3 和 表格 所需的数据信息
            // key = "39.61,-67.88#COESA62#absolute_error#confidenceInterval："
            key = key.replace("：","");
            String[] mapKeyArr = key.split("#");
            String location = mapKeyArr[0];
            String model = mapKeyArr[1];
            String errorType = mapKeyArr[2];

            if ("corrCoee".equalsIgnoreCase(errorType)){ // 39.61,-67.88#COESA62#corrCoee 相关系数是3层，所以就一个简单MAP
                Map<String, Object> locationAndCoee = coeeMap.get(model);
                if (CollUtil.isEmpty(locationAndCoee)){
                    locationAndCoee = new HashMap<>();
                }
                locationAndCoee.put(location, value);
                coeeMap.put(model, locationAndCoee); //前端希望是个数组
                return;
            }

            String resultType = mapKeyArr[3];

            // 这三个errorType都是 模型、站点、resultType
            if ("root_mean_square_error".equalsIgnoreCase(errorType)){
                Map<String, Map<String, Object>> locationAndResultMap = rootMap.get(model);
                if (CollUtil.isEmpty(locationAndResultMap)){
                    locationAndResultMap = new HashMap<>();
                    Map<String, Object> dataMap = new HashMap<>();
                    dataMap.put(resultType, value);
                    locationAndResultMap.put(location, dataMap);
                    rootMap.put(model, locationAndResultMap);
                }else {
                    Map<String, Object> dataMap = locationAndResultMap.get(location);
                    if (CollUtil.isEmpty(dataMap)){
                        dataMap = new HashMap<>();
                    }
                    dataMap.put(resultType, value);
                    locationAndResultMap.put(location, dataMap);
                    rootMap.put(model, locationAndResultMap);
                }
            }

            if ("relative_error".equalsIgnoreCase(errorType)){
                Map<String, Map<String, Object>> locationAndResultMap = relativeErrorMap.get(model);
                if (CollUtil.isEmpty(locationAndResultMap)){
                    locationAndResultMap = new HashMap<>();
                    Map<String, Object> dataMap = new HashMap<>();
                    dataMap.put(resultType, value);
                    locationAndResultMap.put(location, dataMap);
                    relativeErrorMap.put(model, locationAndResultMap);
                }else {
                    Map<String, Object> dataMap = locationAndResultMap.get(location);
                    if (CollUtil.isEmpty(dataMap)){
                        dataMap = new HashMap<>();
                    }
                    dataMap.put(resultType, value);
                    locationAndResultMap.put(location, dataMap);
                    relativeErrorMap.put(model, locationAndResultMap);
                }

            }

            if ("absolute_error".equalsIgnoreCase(errorType)){
                Map<String, Map<String, Object>> locationAndResultMap = absoluteErrorMap.get(model);
                if (CollUtil.isEmpty(locationAndResultMap)){
                    locationAndResultMap = new HashMap<>();
                    Map<String, Object> dataMap = new HashMap<>();
                    dataMap.put(resultType, value);
                    locationAndResultMap.put(location, dataMap);
                    absoluteErrorMap.put(model, locationAndResultMap);
                }else {
                    Map<String, Object> dataMap = locationAndResultMap.get(location);
                    if (CollUtil.isEmpty(dataMap)){
                        dataMap = new HashMap<>();
                    }
                    dataMap.put(resultType, value);
                    locationAndResultMap.put(location, dataMap);
                    absoluteErrorMap.put(model, locationAndResultMap);
                }
            }
        });

        //3.大气模型误差结果统计图
        resultMap.put("absolute_relative",absoluteRelativeMap);
        //4.大气模型误差评估结果统计图
        Map<String, Object> resultErrorMap = new HashMap<>();
        resultErrorMap.put("x", locationList);

        //<model,<location,resultType>>
        Map<String, List<Object>> avg_absolute = absoluteErrorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> {
            return locationList.stream().map(location -> {
                return absoluteErrorMap.get(entry.getKey()).get(location).get("averageResult");
            }).collect(Collectors.toList());
        }));

        Map<String, List<Object>> avg_relative = relativeErrorMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> {
            return locationList.stream().map(location -> {
                return relativeErrorMap.get(entry.getKey()).get(location).get("averageResult");
            }).collect(Collectors.toList());
        }));

        Map<String, List<Object>> coee = coeeMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> {
            return locationList.stream().map(location -> {
                return coeeMap.get(entry.getKey()).get(location);
            }).collect(Collectors.toList());
        }));

        Map<String, List<Object>> root = rootMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> {
            return locationList.stream().map(location -> {
                return rootMap.get(entry.getKey()).get(location).get("result");
            }).collect(Collectors.toList());
        }));

        resultErrorMap.put("avg_absolute", avg_absolute);
        resultErrorMap.put("avg_relative", avg_relative);
        resultErrorMap.put("coee", coee);
        resultErrorMap.put("root", root);

        resultMap.put("error_data",resultErrorMap);

        //表格开始
        List<Map<String,Object>> tableData = new ArrayList<>();
        List<String> modelList = rootMap.entrySet().stream().map(Map.Entry::getKey).distinct().collect(Collectors.toList());
        locationList.forEach( location -> {
            modelList.forEach( model -> {
                Map<String, Object> dataMap = MapUtil.builder(new HashMap<String, Object>())
                        .put("location", location)
                        .put("model", model)
                        .put("corrCoee", coeeMap.get(model).get(location))
                        .put("root", rootMap.get(model).get(location).get("confidenceInterval"))
                        .put("avgAbsolute", absoluteErrorMap.get(model).get(location).get("confidenceInterval"))
                        .put("avgRelative", relativeErrorMap.get(model).get(location).get("confidenceInterval"))
                        .build();
                tableData.add(dataMap);
            });
        });
        resultMap.put("table", tableData);

        //3. 最佳策略结果, 例如：【强磁暴期】最优模型为: 【JB2008】
        List<String> bestModelStrategyList = new JSONArray(contentMap.get("bestModelStrategy")).toList(String.class);
        String result = bestModelStrategyList.stream().map(bestModelStrategy -> {
            String[] split = bestModelStrategy.split("#");
            String location = split[1];
            String model = split[3];
            return location + "最优模型为: " + model;
        }).collect(Collectors.joining("；"));
        resultMap.put("result", result);

        //4. txt文件也要加上
        resultMap.put("txt", txtPath);

        System.out.println(resultMap);


    }



}
